package net.wanho.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import net.wanho.constant.UserConstant;
import net.wanho.dto.UserInfoDTO;
import net.wanho.mapper.*;
import net.wanho.po.*;
import net.wanho.service.UserInfoService;
import net.wanho.util.CurrentUtil;
import net.wanho.vo.AuthVO;
import net.wanho.vo.PageInfo;
import net.wanho.vo.UserInfoVo;
import net.wanho.vo.UserInfoVo2;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author 王洋
* @description 针对表【user_info(用户表)】的数据库操作Service实现
* @createDate 2024-09-03 17:43:36
*/
@Service
@RequiredArgsConstructor
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
    implements UserInfoService{
    private final UserInfoMapper userInfoMapper;
    private final UserRoleMapper userRoleMapper;
    private final RoleAuthMapper roleAuthMapper;
    private final AuthInfoMapper authInfoMapper;
    private final RoleMapper roleMapper;
    private final RedisTemplate<String, Object> redisTemplate;

    @Override
    public PageInfo<UserInfo> listPage(Integer pageNum, Integer pageSize, UserInfoDTO userInfoDTO) {
        Page<UserInfo> page = new Page<>(pageNum, pageSize);
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.like(!ObjectUtils.isEmpty(userInfoDTO.getUserCode()), "i.user_code", userInfoDTO.getUserCode());
        wrapper.eq(!ObjectUtils.isEmpty(userInfoDTO.getRoleId()), "r.role_id", userInfoDTO.getRoleId());
        wrapper.eq(!ObjectUtils.isEmpty(userInfoDTO.getUserState()), "i.user_state", userInfoDTO.getUserState());
        wrapper.orderByAsc("i.user_id");

        this.baseMapper.selectByPage(page, wrapper);

        PageInfo<UserInfo> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page.getCurrent());
        pageInfo.setPageSize(page.getSize());
        pageInfo.setTotalNum(page.getTotal());
        pageInfo.setPageCount(page.getPages());
        pageInfo.setResultList(page.getRecords());
        pageInfo.setLimitIndex((page.getCurrent()-1) * page.getSize());

        page.getRecords().forEach(item -> {
            item.setGetCode(this.getById(item.getCreateBy()).getUserCode());
        });
        return pageInfo;

    }

    @Override
    public List<AuthVO> getAuth() {
        List<AuthVO> menu=(List<AuthVO>) redisTemplate.opsForValue().get(UserConstant.MENU_PREFIX+CurrentUtil.getUserId());
        if (ObjectUtil.isNotEmpty(menu)){
            return menu;
        }
        List<AuthVO> list = authInfoMapper.selectByUserId(CurrentUtil.getUserId());
       List<AuthVO> collect = list.stream().filter(item -> item.getParentId() == 0)
                .map(item -> {
                    findChildren(list, item);
                    return item;
                }).collect(Collectors.toList());
       redisTemplate.opsForValue().set(UserConstant.MENU_PREFIX+CurrentUtil.getUserId(),collect);
       return collect;
    }

    @Override
    public void addUser(UserInfoVo userInfoVo) {
        userInfoVo.setUserPwd(SecureUtil.md5(userInfoVo.getUserPwd()));
        userInfoVo.setUserState(UserConstant.USER_STATE_ENABLE);
        userInfoVo.setIsDelete(UserConstant.USER_DELETE_ENABLE);
        userInfoVo.setCreateBy(CurrentUtil.getUserId());
        userInfoVo.setCreateTime(new Date());
        userInfoVo.setUpdateBy(CurrentUtil.getUserId());
        userInfoVo.setUpdateTime(new Date());
        userInfoMapper.addUser(userInfoVo);
    }

    @Override
    public void updatePwd(Integer id) {
        String newPwd = SecureUtil.md5(UserConstant.DEFAULT_PWD);
        userInfoMapper.updatePwd(id, newPwd);
    }

    @Override
    public List<Role> getUserRoleList(Integer id) {
        List<Role> roleList = userInfoMapper.selectUserRoleList(id);
        return roleList;
    }

    @Override
    public void updateRole(UserInfoVo2 userInfoVo2) {
        userRoleMapper.delete(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, userInfoVo2.getUserId()));
        List<UserRole> list = new ArrayList<>();
        List<Integer> roleId =new ArrayList<>();
        for(String role : userInfoVo2.getRoleCheckList()){
            Integer id=roleMapper.selectByName(role);
            roleId.add(id);
        }
        for (Integer integer : roleId) {
            UserRole userRole=new UserRole();
            userRole.setUserId(userInfoVo2.getUserId());
            userRole.setRoleId(integer);
            list.add(userRole);
        }
        userRoleMapper.insertBatch(list);

        redisTemplate.delete(UserConstant.MENU_PREFIX+userInfoVo2.getUserId());

    }

    @Override
    public List<Integer> getUserAuthIdList(Integer userId) {
        List<Integer> list = userInfoMapper.getUserAuthIdList(userId);
        return list;
    }

    private void findChildren(List<AuthVO> list, AuthVO item) {
        List<AuthVO> children = list.stream().
                filter(subItem -> subItem.getParentId().equals(item.getAuthId()))
                .map(subItem -> {
                    findChildren(list, subItem);
                    return subItem;
                }).collect(Collectors.toList());
        item.setChildAuth(children);
    }




    }





